#include "IIC.h"
/**/

void _iic_delay_nus(uint16_t us)
{
	us *= 10;
	while(us--);
}

void _iic_Start(SOFT_IIC *soft_iic)
{
/*	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	 soft_iic->scl.set_bit(&soft_iic->scl)// SCL::H();	
	delay_nus(10);
	SDA_L();
	delay_nus(10);
*/
	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	soft_iic->delay_nus(50);

	soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
	soft_iic->delay_nus(50);

	soft_iic->sda.reset_bit(&soft_iic->sda);//SDA::L();
	soft_iic->delay_nus(50);

	soft_iic->scl.reset_bit(&soft_iic->scl);////SDA::L();
	soft_iic->delay_nus(50);

		//while(1);
       
}
void _iic_Stop(SOFT_IIC *soft_iic)
{
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);	
	soft_iic->sda.reset_bit(&soft_iic->sda);//SDA::L();		
	soft_iic->delay_nus(10);
	soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
	soft_iic->delay_nus(10);
	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	soft_iic->delay_nus(10);

}
uint8_t _iic_WaitAck(SOFT_IIC *soft_iic)
{
	uint16_t k;
	uint8_t ack =0;
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	soft_iic->delay_nus(10);

	soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
	k = 0;
	while((soft_iic->sda.read(&soft_iic->sda)!= 0) && (k < 600))k++;
	soft_iic->delay_nus(10);
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);	
	if(k < 600 ) ack = 1;
	return ack;
}

void _iic_WriteByte(SOFT_IIC *soft_iic,uint8_t byte)
{
	uint8_t i = 0;
	for(i = 0; i < 8; i++)
	{
		soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
		soft_iic->delay_nus(10);
		if(byte & 0x80)
		{
			soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
		}
		else
		{
			soft_iic->sda.reset_bit(&soft_iic->sda);//SDA::L();
		}
		soft_iic->delay_nus(10);
		soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
		soft_iic->delay_nus(10);
		byte<<=1;
	}
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);
}

uint8_t _iic_ReadByte(SOFT_IIC *soft_iic)
{
	uint8_t i,ReadByte;

	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	for(i = 0; i < 8; i++)
	{	
		ReadByte <<= 1;
		 soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
		soft_iic->delay_nus(10);
		 soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
		 soft_iic->delay_nus(10);
		if(soft_iic->sda.read(&soft_iic->sda))
		{
			ReadByte |= 0x01;
		}
		else
		{
			ReadByte &= ~(0x01);	
		}
				
	}
	return ReadByte;
}
void _iic_Ack(SOFT_IIC *soft_iic)
{        
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);
	soft_iic->sda.reset_bit(&soft_iic->sda);//SDA::L();
	soft_iic->delay_nus(10);
	soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
	soft_iic->delay_nus(10);
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);
}

void _iic_NoAck(SOFT_IIC *soft_iic)
{        
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);
	soft_iic->sda.set_bit(&soft_iic->sda);//SDA::H();
	soft_iic->delay_nus(10);
	soft_iic->scl.set_bit(&soft_iic->scl);// SCL::H();
	soft_iic->delay_nus(10);
	soft_iic->scl.reset_bit(&soft_iic->scl); // SCL::L();
	soft_iic->delay_nus(10);
}


SOFT_IIC new_soft_iic(uint32_t scl_gpiox,uint32_t scl_gpio_pinx,uint32_t sda_gpiox,uint32_t sda_gpio_pinx)
{
	SOFT_IIC temp;
	temp.scl = new_outport(scl_gpiox,scl_gpio_pinx);
	temp.sda = new_opendrainport(sda_gpiox,sda_gpio_pinx);
	temp.ReadByte = _iic_ReadByte;
	temp.WriteByte = _iic_WriteByte;
	temp.WaitAck = _iic_WaitAck;
	temp.Stop = _iic_Stop;
	temp.Start = _iic_Start;
	//temp.Init = _iic_Init;
	temp.Ack = _iic_Ack;
	temp.NoAck = _iic_NoAck;
	temp.delay_nus = _iic_delay_nus;
	return temp;
}
